﻿#define DEBUG
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.Timers;
using System.IO;
using System.Xml.Linq;
using Oroboros.Save_Data;
using Oroboros;
using Oroboros.Objects;

namespace Save_Editor
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public string fzsg_dir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\Fort Zombie Saved Games";
        public GameSaveData saveFile;
        public string file = "";

        public MainWindow()
        {
            InitializeComponent();

            MyInitializer();

#if DEBUG
            btnDbg.Visibility = System.Windows.Visibility.Visible;
#endif

            bmKnownProjects.ItemsSource = Enum.GetNames(typeof(Oroboros.Project));
        }

        public void MyInitializer()
        {
            
        }

        public void SaveTo()
        {
            saveFile.ZombieClock.Clock = myTime.Value;
            saveFile.ZombieClock.IsPaused = checkBox1.IsChecked.Value;
        }

        /// <summary>
        /// Loads content of saveFile and updates the form
        /// </summary>
        public void LoadTo()
        {
            //ZombieClock
            myTime.Value = saveFile.ZombieClock.Clock;
            checkBox1.IsChecked = new bool?(saveFile.ZombieClock.IsPaused);

            //Base Manager
            listTasks.ItemsSource = saveFile.BaseManager.AvailableTasks;
            listGenerators.ItemsSource = saveFile.BaseManager.Generators;
            listDefences.ItemsSource = saveFile.BaseManager.Defences;
            listProjects.ItemsSource = saveFile.BaseManager.KnownProjects;
            InvData.DataContext = saveFile.BaseManager.Inventory;

            //Human manager
            HumanData.DataContext = saveFile.HumanManager;

            //Map
            BaseData.DataContext = new Vector2Wrapper(saveFile.Map.BasePosition);
        }

        private void btnLoad_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.InitialDirectory = fzsg_dir;
            dlg.Filter = "Fort Zombie Saved Game|*.sav|Fort Zombie Saved Game Backup|*.bak";
            if (dlg.ShowDialog().Value)
            {
                file = dlg.FileName;
                try
                {
                    saveFile = Serializer.GetSaveData(file);
                    LoadTo();
                }
                catch (IOException __ioe)
                {
                    MessageBox.Show(__ioe.ToString(), "IO Error", MessageBoxButton.OK, MessageBoxImage.Asterisk);
                }
            }
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            if (!chkAOWrt.IsChecked.Value)
            {
                MessageBoxResult mres = MessageBox.Show("Overwrite the currently opened file? ", "Overwrite Save Game", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
                if (mres == MessageBoxResult.Cancel)
                    return;
                else if (mres == MessageBoxResult.No)
                {
                    SaveFileDialog dlg = new SaveFileDialog();
                    dlg.InitialDirectory = fzsg_dir;
                    dlg.Filter = "Fort Zombie Saved Game|*.sav|Fort Zombie Saved Game Backup|*.bak";
                    if (!dlg.ShowDialog().Value)
                    {
                        return;
                    }
                    file = dlg.FileName;
                }
            }
            bool noBackup = false;
            if (!chkBackup.IsChecked.Value)
            {
                MessageBoxResult mres = MessageBox.Show("Make a backup of the currently opened file? ",
                    "Backup Save Game", MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (mres == MessageBoxResult.No)
                    noBackup = true;
            }
            if (!noBackup)
                Serializer.Backup(file);
            if (string.IsNullOrEmpty(file)) return;
            SaveTo();
            Serializer.SetSaveData(file, saveFile);
            LastAccessed = Accessed;
            MessageBox.Show(string.Format("Fort Zombie Save Game edited and saved successfully.", file), "Save Complete", MessageBoxButton.OK, MessageBoxImage.Information);
        }

        public DateTime Accessed
        {
            get
            {
                FileInfo fInfo = new FileInfo(file);
                return fInfo.LastWriteTime;
            }
        }

        private DateTime LastAccessed = DateTime.Now;

        private void Window_Activated(object sender, EventArgs e)
        {
            if (saveFile == null)
                return;
            if (Accessed.CompareTo(LastAccessed) >= 1)
            {
                this.Activated -= Window_Activated;
                if (MessageBox.Show("The Saved Game file has been changed outside the program. Reload it?", "Reload Saved Game", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    saveFile = Serializer.GetSaveData(file);
                    LastAccessed = Accessed;
                    LoadTo();
                    MessageBox.Show("The Saved Game file has been loaded sucessfully.", "Load Game completed", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                this.Activated+=new EventHandler(Window_Activated);
            }
        }

        private void zcFirstDay(object sender, RoutedEventArgs e)
        {
            myTime.Value = new DateTime(1, 1, 1, 6, 0, 0);
        }

        private void zcDebug(object sender, RoutedEventArgs e)
        {
            //GameSaveData SaveData = Serializer.GetSaveData(file);
            //MessageBox.Show(string.Format("{0}", saveFile.bmBaseManage.Generators.ToElement()), "Debug Message", MessageBoxButton.OK, MessageBoxImage.Asterisk);
            //MessageBox.Show(myTime.Value.ToString("MM/dd/yyyy hh:mm:ss tt"),"Value of CustomDateTime");
            //Classes.AccessorMaker.CreateAccessors(typeof(HumanManager));
            //Serializer.SetSaveData(fzsg_dir + "\\oroboros.sav", SaveData);
        }

        private void zcReset(object sender, RoutedEventArgs e)
        {
            myTime.Value = saveFile.ZombieClock.Clock;
        }

        private void zcAddDay(object sender, RoutedEventArgs e)
        {
            myTime.Value = myTime.Value.AddDays(1);
        }

        private void zcSubDay(object sender, RoutedEventArgs e)
        {
            try
            {
                myTime.Value = myTime.Value.AddDays(-1);
            }
            catch { }
        }

        private void zcFinalDay(object sender, RoutedEventArgs e)
        {
            myTime.Value = myTime.Max.Value;
        }

        private void bmChooseTask(object sender, SelectionChangedEventArgs e)
        {
            if (listTasks.SelectedIndex == -1) return;
            TaskData.Task = saveFile.BaseManager.AvailableTasks[listTasks.SelectedIndex];
        }

        private void bmChooseGenerator(object sender, SelectionChangedEventArgs e)
        {
            if (listGenerators.SelectedIndex == -1) return;
            GenData.Generator = saveFile.BaseManager.Generators[listGenerators.SelectedIndex];
        }

        private void bmChooseDefence(object sender, SelectionChangedEventArgs e)
        {
            if (listDefences.SelectedIndex == -1) return;
            DefData.Defence = saveFile.BaseManager.Defences[listDefences.SelectedIndex];
        }

        private void bmChooseProject(object sender, SelectionChangedEventArgs e)
        {
            if (listProjects.SelectedIndex == -1) return;
            bmKnownProjects.Text = saveFile.BaseManager.KnownProjects[listProjects.SelectedIndex].ToString();
        }

        private void bmUnlockProject(object sender, RoutedEventArgs e)
        {
            if (bmKnownProjects.SelectedIndex == -1) return;
            saveFile.BaseManager.KnownProjects.Add((Oroboros.Project)Enum.Parse(typeof(Oroboros.Project), bmKnownProjects.Text));
        }

        private void cheatGenerators(object sender, RoutedEventArgs e)
        {
            if (saveFile == null) return;
            foreach (GeneratorSaveData generator in saveFile.BaseManager.Generators)
            {
                generator.DailyFuelRequired = 1;
                generator.Output = 999;
                generator.MaxOutput = 999;
                generator.Health = 999;
                generator.MaxHealth = 999;
                generator.PoweredLights = true;
                generator.Enabled = true;
            }
            cheatMsg("Generators altered.");
        }

        private void cheatDefences(object sender, RoutedEventArgs e)
        {
            if (saveFile == null) return;
            foreach (DefenceSaveData defence in saveFile.BaseManager.Defences)
            {
                if (defence.DefenceClassName.Contains("barricade"))
                {
                    defence.DefenceClassName = defence.DefenceClassName.Replace("Light", "Heavy").Replace("Medium", "Heavy");
                    defence.CompletedModel = defence.CompletedModel.Replace("Level01", "Level03").Replace("Level02", "Level03");
                }
                defence.IsUnderConstruction = false;
                saveFile.BaseManager.AvailableTasks.RemoveDefence(defence.Guid);
            }
            cheatMsg("Defences built.");
        }

        private void cheatBaseInventory(object sender, RoutedEventArgs e)
        {
            if (saveFile == null) return;
            saveFile.BaseManager.Inventory.MaxItems();
            cheatMsg("Inventory expanded, and items maxed.");
        }

        private void cheatHumans(object sender, RoutedEventArgs e)
        {
            if (saveFile == null) return;
            saveFile.HumanManager.Humans.MaxStats();
            cheatMsg("Human stats maxed.");
        }

        private void cheatHumanSkills(object sender, RoutedEventArgs e)
        {
            if (saveFile == null) return;
            saveFile.HumanManager.Humans.MaxSkills();
            cheatMsg("Human skills maxed.");
        }

        private void cheatHumanHealth(object sender, RoutedEventArgs e)
        {
            if (saveFile == null) return;
            saveFile.HumanManager.Humans.MaxHealth();
            cheatMsg("Humans healed.");
        }

        private void cheatHumanItems(object sender, RoutedEventArgs e)
        {
            if (saveFile == null) return;
            saveFile.HumanManager.Humans.MaxItems();
            cheatMsg("Human inventories expanded, and items maxed.");
        }

        private void cheatMsg(string msg)
        {
            MessageBox.Show(msg + Environment.NewLine + "Please remember to save the changes you make."
                , "Completed", MessageBoxButton.OK, MessageBoxImage.Exclamation);
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Properties.Settings.Default.Save();
        }
    }
}
